/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */
/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */
#include "AT32Models.h"
#include <string.h>
// #include "USART_Configuration.h"
const AT32_MCU_TYPE AT32_MCU_LIST[AT32_MCU_MODEL_COUNT] = {
    {0x27, 0x50240, __AT32F403ZCT6, _256KB, LQFP144},
    {0x27, 0x50241, __AT32F403VCT6, _256KB, LQFP100},
    {0x27, 0x50242, __AT32F403RCT6, _256KB, LQFP64},
    {0x27, 0x50243, __AT32F403CCT6, _256KB, LQFP48},
    {0x27, 0x50344, __AT32F403ZGT6, _1024KB, LQFP144},
    {0x27, 0x50345, __AT32F403VGT6, _1024KB, LQFP100},
    {0x27, 0x50346, __AT32F403RGT6, _1024KB, LQFP64},
    {0x27, 0x50347, __AT32F403CGT6, _1024KB, LQFP48},
    {0x27, 0x502C8, __AT32F403ZET6, _512KB, LQFP144},
    {0x27, 0x502C9, __AT32F403VET6, _512KB, LQFP100},
    {0x27, 0x502CA, __AT32F403RET6, _512KB, LQFP64},
    {0x27, 0x502CB, __AT32F403CET6, _512KB, LQFP48},
    {0x27, 0x5034C, __AT32F403CGU6, _1024KB, QFN48},
    {0x27, 0x502CD, __AT32F403CEU6, _512KB, QFN48},
    {0x27, 0x5024E, __AT32F403CCU6, _256KB, QFN48},
    {0x47, 0x30240, __AT32F413RCT7, _256KB, LQFP64},
    {0x47, 0x301C1, __AT32F413RBT7, _128KB, LQFP64},
    {0x47, 0x30242, __AT32F413CCT7, _256KB, LQFP48},
    {0x47, 0x301C3, __AT32F413CBT7, _128KB, LQFP48},
    {0x47, 0x30244, __AT32F413KCU7_4, _256KB, QFN32},
    {0x47, 0x301C5, __AT32F413KBU7_4, _128KB, QFN32},
    {0x47, 0x30106, __AT32F413C8T7, _64KB, LQFP48},
    {0x47, 0x30247, __AT32F413CCU7, _256KB, QFN48},
    {0x47, 0x301C0, __AT32F413CBU7, _128KB, QFN48},
    {0x57, 0x30240, __AT32F415RCT7, _256KB, LQFP64},
    {0x57, 0x30241, __AT32F415CCT7, _256KB, LQFP48},
    {0x57, 0x30242, __AT32F415KCU7_4, _256KB, QFN32},
    {0x57, 0x30243, __AT32F415RCT7_7, _256KB, LQFP64},
    {0x57, 0x301C4, __AT32F415RBT7, _128KB, LQFP64},
    {0x57, 0x301C5, __AT32F415CBT7, _128KB, LQFP48},
    {0x57, 0x301C6, __AT32F415KBU7_4, _128KB, QFN32},
    {0x57, 0x301C7, __AT32F415RBT7_7, _128KB, LQFP64},
    {0x57, 0x30108, __AT32F415R8T7, _64KB, LQFP64},
    {0x57, 0x30109, __AT32F415C8T7, _64KB, LQFP48},
    {0x57, 0x3010B, __AT32F415R8T7_7, _64KB, QFN32},
    {0x57, 0x3010A, __AT32F415K8U7_4, _64KB, LQFP64},
    {0x57, 0x301CD, __AT32F415CBU7, _128KB, QFN48},
    {0x57, 0x3024C, __AT32F415CCU7, _256KB, QFN48},
    {0x77, 0x50240, __AT32F403AVCT7, _256KB, LQFP100},
    {0x77, 0x50241, __AT32F403ARCT7, _256KB, LQFP64},
    {0x77, 0x50242, __AT32F403ACCT7, _256KB, LQFP48},
    {0x77, 0x50243, __AT32F403ACCU7, _256KB, QFN48},
    {0x77, 0x50344, __AT32F403AVGT7, _1024KB, LQFP100},
    {0x77, 0x50345, __AT32F403ARGT7, _1024KB, LQFP64},
    {0x77, 0x50346, __AT32F403ACGT7, _1024KB, LQFP48},
    {0x77, 0x50347, __AT32F403ACGU7, _1024KB, QFN48},
    {0x77, 0x502CD, __AT32F403AVET7, _512KB, LQFP100},
    {0x77, 0x502CE, __AT32F403ARET7, _512KB, LQFP64},
    {0x77, 0x503CF, __AT32F403ACET7, _512KB, LQFP48},
    {0x77, 0x503D0, __AT32F403ACEU7, _512KB, QFN48},
    {0x87, 0x50249, __AT32F407VCT7, _256KB, LQFP100},
    {0x87, 0x5024A, __AT32F407RCT7, _256KB, LQFP64},
    {0x87, 0x5034B, __AT32F407VGT7, _1024KB, LQFP100},
    {0x87, 0x5034C, __AT32F407RGT7, _1024KB, LQFP64},
    {0x87, 0x502D1, __AT32F407VET7, _512KB, LQFP100},
    {0x87, 0x502D2, __AT32F407RET7, _512KB, LQFP64},
};
const uint32_t at32_mcu_flash_size[AT32_MCU_FLASH_COUNT] =
{
    0x10000,
    0x20000,
    0x40000,
    0x80000,
    0x100000,
};
const char AT32_MCU_Model_str[AT32_MCU_MODEL_COUNT + 1][16] =
    {
        "AT32F403ZCT6",
        "AT32F403VCT6",
        "AT32F403RCT6",
        "AT32F403CCT6",
        "AT32F403ZGT6",
        "AT32F403VGT6",
        "AT32F403RGT6",
        "AT32F403CGT6",
        "AT32F403ZET6",
        "AT32F403VET6",
        "AT32F403RET6",
        "AT32F403CET6",
        "AT32F403CGU6",
        "AT32F403CEU6",
        "AT32F403CCU6",
        "AT32F413RCT7",
        "AT32F413RBT7",
        "AT32F413CCT7",
        "AT32F413CBT7",
        "AT32F413KCU7-4",
        "AT32F413KBU7-4",
        "AT32F413C8T7",
        "AT32F413CCU7",
        "AT32F413CBU7",
        "AT32F415RCT7",
        "AT32F415CCT7",
        "AT32F415KCU7-4",
        "AT32F415RCT7-7",
        "AT32F415RBT7",
        "AT32F415CBT7",
        "AT32F415KBU7-4",
        "AT32F415RBT7-7",
        "AT32F415R8T7",
        "AT32F415C8T7",
        "AT32F415R8T7-7",
        "AT32F415K8U7-4",
        "AT32F415CBU7",
        "AT32F415CCU7",
        "AT32F403AVCT7",
        "AT32F403ARCT7",
        "AT32F403ACCT7",
        "AT32F403ACCU7",
        "AT32F403AVGT7",
        "AT32F403ARGT7",
        "AT32F403ACGT7",
        "AT32F403ACGU7",
        "AT32F403AVET7",
        "AT32F403ARET7",
        "AT32F403ACET7",
        "AT32F403ACEU7",
        "AT32F407VCT7",
        "AT32F407RCT7",
        "AT32F407VGT7",
        "AT32F407RGT7",
        "AT32F407VET7",
        "AT32F407RET7",
        "unknown",
};
const char AT32_MCU_FLASH_str[AT32_MCU_FLASH_COUNT + 1][8] =
    {
        "64KB",
        "128KB",
        "256KB",
        "512KB",
        "1024KB",
        "unknown",
};
const char AT32_MCU_Footprint_str[AT32_MCU_Footprint_COUNT + 1][8] =
    {
        "QFN32",
        "QFN48",
        "LQFP48",
        "LQFP64",
        "LQFP100",
        "LQFP144",
        "unknown",
};
const char AT32_MCU_Cortex_str[Cortex_count + 1][16] =
    {
        "Cortex-M0-r0p0",
        "Cortex-M0+-r0p0",
        "Cortex-M1-r0p1",
        "Cortex-M1-r0p1",
        "Cortex-M1-r1p0",
        "Cortex-M3-r0p0",
        "Cortex-M3-r1p0",
        "Cortex-M3-r1p1",
        "Cortex-M3-r2p0",
        "Cortex-M3-r2p1",
        "Cortex-M4-r0p0",
        "Cortex-M4-r0p1",
        "unknown",
};
const uint32_t AT32_MCU_CORE_ID[Cortex_count] =
    {
        0x410CC200,
        0x410CC600,
        0x410CC210,
        0x410CC211,
        0x411CC210,
        0x410FC230,
        0x410FC231,
        0x411FC231,
        0x412FC230,
        0x412FC231,
        0x410FC240,
        0x410FC241,

};
char *at32_mcu_mode2str(AT32_MCU_TYPE *mcu)
{
    if (mcu->Model < AT32_MCU_MODEL_COUNT)
        return (char *)AT32_MCU_Model_str[mcu->Model];
    else
        return (char *)AT32_MCU_Model_str[AT32_MCU_MODEL_COUNT];
}
char *at32_mcu_flash2str(AT32_MCU_TYPE *mcu)
{
    if (mcu->Flash < AT32_MCU_FLASH_COUNT)
        return (char *)AT32_MCU_FLASH_str[mcu->Flash];
    else
        return (char *)AT32_MCU_FLASH_str[AT32_MCU_FLASH_COUNT];
}
char *at32_mcu_footprint2str(AT32_MCU_TYPE *mcu)
{
    if (mcu->Footprint < AT32_MCU_Footprint_COUNT)
        return (char *)AT32_MCU_Footprint_str[mcu->Footprint];
    else
        return (char *)AT32_MCU_Footprint_str[AT32_MCU_Footprint_COUNT];
}
uint8_t at32_mcu_who_am_i(AT32_MCU_TYPE *mcu)
{
    uint8_t serial = AT32_MCU_SERIAL_ID;
    uint32_t id = AT32_MCU_PID;
    serial = ((id >> 28) | (serial << 4));
    id = id & 0xFFFFF;
    // usartPrintf(">>s:%d - id:%d\n\n", serial, id);
    AT32MCU_FOREACH(i)
    {
        // usartPrintf(">>s:%d - %d\n\n", AT32_MCU_LIST[i].Serial, AT32_MCU_LIST[i].ID);
        if ((AT32_MCU_LIST[i].Serial == serial) && (AT32_MCU_LIST[i].ID == id))
        {
            mcu->Serial = serial;
            mcu->ID = id;
            mcu->Model = AT32_MCU_LIST[i].Model;
            mcu->Flash = AT32_MCU_LIST[i].Flash;
            mcu->Footprint = AT32_MCU_LIST[i].Footprint;
            return 0;
        }
    }
    mcu->Serial = serial;
    mcu->ID = id;
    mcu->Model = AT32_MCU_MODEL_COUNT;
    mcu->Flash = AT32_MCU_Footprint_COUNT;
    mcu->Footprint = AT32_MCU_Footprint_COUNT;

    return 1;
}
uint32_t at32_mcu_get_coreID(void)
{
    /*
    内核的系统控制块（SCB） 中存在一个名为CPU ID基本寄存器的寄存器， 它是只读的， 其中包括处
    理器类型和版本号。该寄存器的地址为0XE000ED00（只支
    持特权访问），在程序中， 可以利用SCB->CPUID访问该寄存器，也可通过绝对地址访问，如
    *(uint32_t *)0xE000ED00。
    */
    return *(uint32_t *)0xE000ED00;
}
char *at32_mcu_core2str(uint32_t id)
{
    for (uint16_t i = 0; i < Cortex_count; i++)
    {
        if (id == AT32_MCU_CORE_ID[i])
            return (char *)AT32_MCU_Cortex_str[i];
    }
    return (char *)AT32_MCU_Cortex_str[Cortex_count];
}
uint8_t at32_mcu_init_model(AT32_MCU_TYPE *mcu, char *model)
{
    for(uint16_t i = 0; i < AT32_MCU_MODEL_COUNT; i++)
    {
        if(strcmp(model, AT32_MCU_Model_str[i]) == 0)
        {
            memcpy(mcu, &AT32_MCU_LIST[i], sizeof(AT32_MCU_TYPE));
            return 0;
        }
    }
    mcu->Serial = 0;
    mcu->ID = 0;
    mcu->Model = AT32_MCU_MODEL_COUNT;
    mcu->Flash = AT32_MCU_Footprint_COUNT;
    mcu->Footprint = AT32_MCU_Footprint_COUNT;
    return 1;
}
